home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Commodities / RMBShift / RMBShift.asm < prev    next >
Assembly Source File  |  1996-09-26  |  15KB  |  549 lines

  1.  
  2. *    RMBShift
  3. *    By Preben Nielsen
  4. *
  5. *    This small program makes it possible for the right mouse-button to
  6. *       act as a shift key. This means that it will be possible to select
  7. *       multiple icons on the workbench without having to press a Shift-Key.
  8. *
  9. *    Once installed, the program only uses 268 bytes of memory.
  10. *    To get back to normal simply run the program again.
  11. *
  12. *    NOTE:    There's no need to 'RUN' or 'RUNBACK' this program from the
  13. *        CLI. It terminates immediately.
  14. *
  15. *HISTORY
  16. *          Made with Hisoft V2.12
  17. *
  18. *  V1.0   01-Sep-91: First attempt. Works of course.
  19. *  V2.0   22-Sep-91: Now works completely different.
  20.  
  21.  
  22.     OPT O+
  23.     OPT O1+            ; Tells when a branch could be optimised to short
  24.     OPT i+            ; Tells when '#' is probably missing
  25.  
  26.         incdir        "AsmInc:"
  27.         include        "P.i"
  28.         include        "relMacros.i"
  29.         include        "exec/exec_lib.i"
  30.         include        "exec/io.i"
  31.         include        "exec/memory.i"
  32.         include        "exec/interrupts.i"
  33.         include        "devices/input.i"
  34.         include        "devices/inputevent.i"
  35.         include        "libraries/dosextens.i"
  36.         include        "libraries/dos_lib.i"
  37.         include        "intuition/intuition.i"
  38.  
  39. DB        EQUR        A4
  40.  dcDeclare    A4
  41.  dcAPtr        PProcess
  42.  dcAPtr        WBMsg
  43.  dcAPtr        DosBase
  44.  dcAPtr        HMem
  45.  dcEnd
  46.  
  47. Start        dcAlloc                    ; Allocate memory for variables
  48.         dcReset                    ; Clear the memory
  49.         Prepare        Exec_Call
  50.         suba.l        A1,A1
  51.         CallLib        FindTask        ; Find us
  52.         move.l        D0,PProcess(DB)
  53.         movea.l        D0,A2
  54.         tst.l        pr_CLI(A2)
  55.         bne.S        GetLibs
  56. WBStart        lea        pr_MsgPort(A2),A0
  57.         CallLib        WaitPort        ; wait for a message
  58.         lea        pr_MsgPort(A2),A0
  59.         CallLib        GetMsg            ; then get it
  60.         move.l        D0,WBMsg(DB)        ; save it for later reply
  61. GetLibs        lea        DosName(PC),A1
  62.         CallLib        OldOpenLibrary
  63.         move.l        D0,DosBase(DB)
  64.         beq.S        Error
  65.         lea        IHSName(PC),A1
  66.         Call        FindThisPort
  67.         beq.S        DoInstall
  68. DoRemove    moveq        #REMOVED,D7
  69.         lea        IHS(PC),A0
  70.         lea        PSEndIHS1(PC),A1
  71.         lea        PSEndIHS2(PC),A2
  72.         Call        RemoveHandler
  73.         beq.S        ShowMsg
  74.         moveq        #CANTREMOVE,D7
  75.         bra.S        ShowMsg
  76. DoInstall    moveq        #INSTALLED,D7
  77.         lea        IHS(PC),A0
  78.         lea        PSPrepIHS1(PC),A1
  79.         lea        PSPrepIHS2(PC),A2
  80.         Call        InstallHandler
  81.         beq.S        ShowMsg
  82.         moveq        #CANTINSTALL,D7
  83. ShowMsg        move.l        D7,D0
  84.         Call        CONMsg
  85.  
  86. Error
  87. Exit        Prepare        Exec_Call
  88. FreeDos        move.l        DosBase(DB),D0
  89.         beq.S        ReplyWB
  90.         move.l        D0,A1
  91.         CallLib        CloseLibrary
  92. ReplyWB        move.l        WBMsg(DB),D2
  93.         beq.S        AllDone
  94.         CallLib        Forbid            ; We were started from WB
  95.         movea.l        D2,A1
  96.         CallLib        ReplyMsg        ; Reply WBMessage
  97. AllDone        dcFree
  98.         moveq        #0,D0
  99.         rts
  100.  
  101. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  102. *»»» Console message routines »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  103. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  104. FHandle        EQUR        D5
  105. *»»» Call:    D0 = Msg-number
  106. *»»» Writes a general copyright message and then a more specific message.
  107. *»»» Writes to standard output when run from CLI, and opens its own window
  108. *»»» when run from Workbench.
  109. CONMsg        Push        D0-D7/A0-A6
  110.         Prepare        Dos_Call
  111.         move.l        D0,D4
  112.         moveq        #0,D6
  113.         CallLib        Output
  114.         move.l        D0,FHandle
  115.         bne.S        1$
  116.         moveq        #1,D6
  117.         lea        CONName(PC),A0
  118.         move.l        A0,D1
  119.         move.l        #MODE_OLDFILE,D2
  120.         CallLib        Open
  121.         move.l        D0,FHandle
  122.         beq.S        2$
  123. 1$        moveq        #INFOMSG,D0
  124.         Call        SendMsg
  125.         move.l        D4,D0
  126.         Call        SendMsg
  127.         tst.l        D6
  128.         beq.S        2$
  129.         moveq        #127,D1
  130.         CallLib        Delay
  131.         move.l        FHandle,D1
  132.         CallLib        Close
  133. 2$        Pop        D0-D7/A0-A6
  134.         rts
  135.  
  136. *»»» Call:    D0 = Msg-number
  137. SendMsg        neg.l        D0
  138.         lsl.l        #1,D0
  139.         lea        CONMsgTable(PC),A0
  140.         add.w        0(A0,D0),A0
  141.         move.l        A0,D2
  142.         moveq        #-1,D3
  143. 1$        addq.l        #1,D3
  144.         tst.b        (A0)+
  145.         bne.S        1$
  146.         move.l        FHandle,D1
  147.         Prepare        Dos_Call
  148.         CallLib        Write
  149.         rts
  150.  
  151. INFOMSG        =0
  152. INSTALLED    =-1
  153. REMOVED        =-2
  154. CANTINSTALL    =-3
  155. CANTREMOVE    =-4
  156.  
  157. CONText        MACRO
  158.         dc.w        \1-CONMsgTable
  159.         ENDM
  160. CONMsgTable    CONText        Msg
  161.         CONText        Msg1
  162.         CONText        Msg2
  163.         CONText        Msg3
  164.         CONText        Msg4
  165.  
  166. CONName        dc.b        'CON:100/60/330/63/RMBShift',0
  167. Msg        dc.b        10,$9B,'0;33m RMBShift V2.0',10
  168.         dc.b        $9B,'0;31m 1991 by ',$9B,'0;33mPreben Nielsen',$9B,'0;31m',10,' ',0
  169. Msg1        dc.b        'has now been installed...',10,0
  170. Msg2        dc.b        'has now been removed...',10,0
  171. Msg3        dc.b        "Error: Can't install handler",10,0
  172. Msg4        dc.b        "Error: Can't remove handler",10,0
  173.         EVEN
  174. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  175. *»»» End of Console message routines »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  176. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  177.  
  178. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  179. *»»» Inputhandler removal and installation routines »»»»»»»»»»»»»»»»»»»»»»»»
  180. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  181. rtsValue    EQUR        D7
  182. *»»» This is general-purpose inputhandler removal-routine
  183. *»»» It only needs an ihs with a port-name to remove the handler
  184. *»»» Call:    A0 = ihs
  185. *»»»        A1 = first ihs-installation-routine or NULL
  186. *»»»        A2 = second ihs-installation-routine or NULL
  187. *»»» Return:    D0 = 0 means succes
  188. RemoveHandler    Push        D1/rtsValue/A0-A3/A6
  189.         moveq        #-1,rtsValue
  190.         move.l        A2,A3
  191.         move.l        A0,A2
  192.         move.l        A1,D1
  193.         beq.S        1$
  194.         jsr        (A1)        ; A0 = ihs
  195.         beq.S        2$
  196.         move.l        D0,A2
  197. 1$        move.l        A2,A0
  198.         Prepare        Exec_Call
  199.         moveq        #IND_REMHANDLER,D0
  200.         Call        TellInputDevice
  201.         move.l        D0,rtsValue
  202.         bne.S        2$
  203.         lea        ihs_Port(A2),A1
  204.         CallLib        RemPort
  205.         moveq        #0,D0
  206.         bra.S        3$
  207. 2$        moveq        #-1,D0
  208. 3$        move.l        A3,D1
  209.         beq.S        4$
  210.         move.l        A2,A0
  211.         jsr        (A3)        ; A0 = ihs, D0 = 0 means succes
  212. 4$        move.l        rtsValue,D0
  213.         Pop        D1/rtsValue/A0-A3/A6
  214.         rts
  215.  
  216. *»»» This is general-purpose inputhandler installation-routine
  217. *»»» It only needs an ihs with a port-name to install the handler
  218. *»»» Call:    A0 = ihs
  219. *»»»        A1 = first ihs-installation-routine or NULL
  220. *»»»        A2 = second ihs-installation-routine or NULL
  221. *»»» Return:    D0 = 0 means succes
  222. InstallHandler    Push        D1/rtsValue/A0-A3/A6
  223.         moveq        #-1,rtsValue
  224.         move.l        A2,A3
  225.         move.l        A0,A2
  226.         move.l        A1,D1
  227.         beq.S        1$
  228.         jsr        (A1)        ; A0 = ihs
  229.         beq.S        2$
  230.         move.l        D0,A2
  231. 1$        move.l        A2,A0
  232.         moveq        #IND_ADDHANDLER,D0
  233.         Call        TellInputDevice
  234.         move.l        D0,rtsValue
  235.         bne.S        2$
  236.         lea        ihs_Port(A2),A1
  237.         move.l        ihs_PortName(A2),MP+LN_NAME(A1)    ;MsgPort->mp_Node.ln_Name=Name;
  238.         clr.b        MP+LN_PRI(A1)            ;MsgPort->mp_Node.ln_Pri =0;
  239.         move.b        #NT_MSGPORT,MP+LN_TYPE(A1)    ;MsgPort->mp_Node.ln_Type=NT_MSGPORT;
  240.         move.b        #PA_IGNORE,MP_FLAGS(A1)        ;MsgPort->mp_Flags     =PA_IGNORE;
  241.         Prepare        Exec_Call
  242.         CallLib        AddPort
  243.         moveq        #0,D0
  244.         bra.S        3$
  245. 2$        moveq        #-1,D0
  246. 3$        move.l        A3,D1
  247.         beq.S        4$
  248.         move.l        A2,A0
  249.         jsr        (A3)        ; A0 = ihs, D0 = 0 means succes
  250. 4$        move.l        rtsValue,D0
  251.         Pop        D1/rtsValue/A0-A3/A6
  252.         rts
  253.  
  254. *»»» Open the input device. Set up the I/O block to add or remove the
  255. *»»» input handler, and send the request to the input device. Finally,
  256. *»»» close the device
  257. *»»» Call:    A0 = ihs
  258. *»»»        D0 = Function to perform (IND_ADDHANDLER/IND_REMHANDLER)
  259. *»»» Return:    D0 = 0 means succes
  260.  dcDeclare    A5
  261.  dcArea        IReq,IOSTD_SIZE
  262.  dcArea        IPort,MP_SIZE
  263.  dcEnd
  264. TellInputDevice    dcAlloc
  265.         dcReset
  266.         Push        D1-D2/rtsValue/A0-A3/A6
  267.         Prepare        Exec_Call
  268.         moveq        #-1,rtsValue
  269.         move.l        D0,D2
  270.         move.l        A0,A2
  271.         lea        IPort(A5),A3
  272.         move.b        #NT_MSGPORT,MP+LN_TYPE(A3)    ; mp_Node.ln_Type=NT_MSGPORT;
  273.         move.b        #PA_SIGNAL,MP_FLAGS(A3)        ; mp_Flags    =PA_SIGNAL;
  274.         moveq        #-1,D0
  275.         CallLib        AllocSignal
  276.         move.b        D0,MP_SIGBIT(A3)        ; mp_SigBit    =MPSigBit;
  277.         bmi.S        2$
  278.         suba.l        A1,A1
  279.         CallLib        FindTask
  280.         move.l        D0,MP_SIGTASK(A3)        ; mp_SigTask     =FindTask(0);
  281.         lea        MP_MSGLIST(A3),A0
  282.         NEWLIST        A0
  283.         lea        IReq(A5),A1
  284.         move.l        A3,IO+MN_REPLYPORT(A1)        ; ExtReq->io_Message.mn_ReplyPort   =taskReplyPort;
  285.         move.b        #NT_MESSAGE,IO+MN+LN_TYPE(A1)    ; ExtReq->io_Message.mn_Node.ln_Type=NT_MESSAGE;
  286.         lea        InputName(PC),A0        ; input.device
  287.         moveq        #0,D0                ; unit#
  288.         moveq        #0,D1                ; flags
  289.         CallLib        OpenDevice
  290.         tst.w        D0                ; flag: error if > 0
  291.         bne.S        1$
  292.         lea        IReq(A5),A1
  293.         move.w        D2,IO_COMMAND(A1)
  294.         lea        ihs_Interrupt(A2),A0
  295.         move.l        A0,IO_DATA(A1)
  296.         CallLib        DoIO
  297.         move.l        D0,rtsValue
  298.         lea        IReq(A5),A1
  299.         CallLib        CloseDevice
  300. 1$        move.b        MP_SIGBIT(A3),D0
  301.         CallLib        FreeSignal
  302. 2$        move.l        rtsValue,D0
  303.         Pop        D1-D2/rtsValue/A0-A3/A6
  304.         dcFree
  305.         rts
  306.  
  307. *»»» Each handler should have such a pair of installation-routines.
  308. *»»» The first one is passed to InstallHandler in A1, and it
  309. *»»» is called immediately when entering InstallHandler.
  310. *»»» The second one is passed to InstallHandler in A2, and it
  311. *»»» is called if installation of handler and message-port succeeds.
  312. *»»» -----------------------------------------------------------------
  313. *»»» Call:    A0 = ihs
  314. *»»» Return:    D0 has to point to ihs to be used when installation proceeds.
  315. *»»»        If D0 = 0 then installation is aborted.
  316. PSPrepIHS1    Push        D1-D2/A0-A1/A6
  317.         Prepare        Exec_Call
  318.         lea        IntuiName(PC),A1
  319.         CallLib        OldOpenLibrary            ; Hmm, I never close it again.
  320.         move.l        D0,D2
  321.         beq.S        2$
  322.         move.l        #HandlerSize,D0
  323.         move.l        #MEMF_PUBLIC|MEMF_CLEAR,D1
  324.         CallLib        AllocMem
  325.         move.l        D0,HMem(DB)
  326.         beq.S        2$
  327.         move.l        D0,A1
  328.         lea        IHS(PC),A0
  329.         move.l        #HandlerSize,D0
  330.         Push        D0/A0-A1
  331.         CallLib        CopyMem
  332.         Pop        D0/A0-A1
  333.         move.l        D0,ihs_Length(A1)        ; This will enable removal by other programs
  334.         move.l        D2,IntuiBase-IHS(A1)        ; Give IntuiBase value
  335.         lea        HandlerCode-IHS(A1),A0
  336.         move.l        A0,ihs_Interrupt+IS_CODE(A1)    ; ihs_Interrupt.is_Code = Handler
  337.         clr.l        ihs_Interrupt+IS_DATA(A1)    ; ihs_Interrupt.is_Data = 0
  338.         lea        IHSName-IHS(A1),A0
  339.         move.l        A0,ihs_PortName(A1)        ; ihs_PortName          = IHSName
  340.         move.b        #HPRI,ihs_Interrupt+LN_PRI(A1)    ; ihs_Interrupt.is_Node.ln_Pri = HPRI
  341.         move.l        A1,D0
  342. 2$        Pop        D1-D2/A0-A1/A6
  343.         rts
  344. *»»» Call:    A0 = ihs
  345. *»»»        D0 = 0 means everything went perfect
  346. *»»»        -1 means something went wrong during installation
  347. PSPrepIHS2    Push        D0-D1/A0-A1/A6
  348.         tst.l        D0
  349.         beq.S        1$
  350.         move.l        HMem(DB),D0
  351.         beq.S        1$
  352.         move.l        D0,A1
  353.         move.l        #HandlerSize,D0
  354.         Prepare        Exec_Call
  355.         CallLib        FreeMem
  356. 1$        Pop        D0-D1/A0-A1/A6
  357.         rts
  358.  
  359. *»»» Each handler should have such a pair of ending-routines.
  360. *»»» The first one is passed to RemoveHandler in A1, and it
  361. *»»» is called immediately when entering RemoveHandler.
  362. *»»» The second one is passed to RemoveHandler in A2, and it
  363. *»»» is called if removal of handler and message-port succeeds.
  364. *»»» -----------------------------------------------------------------
  365. *»»» Call:    A0 = ihs
  366. *»»» Return:    D0 has to point to ihs to be used when removal proceeds
  367. *»»»        If D0 = 0 then removal is aborted
  368. PSEndIHS1    Push        A1
  369.         lea        IHSName(PC),A1
  370.         Call        FindThisPort
  371.         Pop        A1
  372.         rts
  373. *»»» Call:    A0 = ihs
  374. *»»»        D0 = 0 means everything went perfect
  375. *»»»        -1 means something went wrong during removal
  376. PSEndIHS2    Push        D0-D1/A0-A1/A6
  377.         tst.l        D0
  378.         bmi.S        1$
  379.         Prepare        Exec_Call
  380.         move.l        ihs_Length(A0),D0
  381.         move.l        A0,A1
  382.         CallLib        FreeMem
  383. 1$        Pop        D0-D1/A0-A1/A6
  384.         rts
  385.  
  386. *»»» Call:    A1 = Portname
  387. *»»» Return:    D0 = Port or NULL (cc reflects result also)
  388. FindThisPort    Push        D1-D2/A0-A1/A6
  389.         Prepare        Exec_Call
  390.         move.l        A1,D2
  391.         CallLib        Forbid
  392.         move.l        D2,A1
  393.         CallLib        FindPort
  394.         move.l        D0,D2
  395.         CallLib        Permit
  396.         move.l        D2,D0
  397.         Pop        D1-D2/A0-A1/A6
  398.         rts
  399.  
  400. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  401. *»»» Input-handler start »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  402. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  403. ihs_Port    =0
  404. ihs_Interrupt    =MP_SIZE
  405. ihs_ID        =MP_SIZE+IS_SIZE
  406. ihs_Length    =MP_SIZE+IS_SIZE+4
  407. ihs_Flags    =MP_SIZE+IS_SIZE+8
  408. ihs_PortName    =MP_SIZE+IS_SIZE+10
  409. ihs_LocalArea    =MP_SIZE+IS_SIZE+14
  410. ihs_SIZE    =MP_SIZE+IS_SIZE+14
  411.  
  412. ihs_Start    MACRO
  413.         dcb.b        MP_SIZE        ; Message-Port structure
  414.         dcb.b        IS_SIZE        ; Interrupt structure
  415.         dc.l        'P_IH'        ; ID
  416.         dc.l        0        ; Length of handler 
  417.         dc.w        0        ; Flags
  418.         dc.l        0
  419.         ENDM
  420.  
  421. HPRI        =55
  422. HDisabled    =0
  423. HNoExtRemoval    =1
  424.  
  425. *»»» This is the handler-block
  426. IHS        ihs_Start
  427. *»»» Put local data here
  428. IntuiBase    dc.l        0
  429. State        dc.w        0
  430.  
  431. ENABLED        =0
  432. DOING_SHIFT    =1
  433.  
  434. *»»» IHS name
  435. IHSName        dc.b        'RMBShift V2.0 Port',0
  436.         EVEN
  437. *»»» For each event in the event list:
  438. *»»»  If we were waiting for this event then signal the task.
  439. *»»» When all the events have been checked, return the event list so that
  440. *»»» others can do their things.
  441. EList        EQUR    A0
  442. Event        EQUR    A1
  443.  
  444. Next        =ie_NextEvent
  445. Class        =ie_Class
  446. Code        =ie_Code
  447. Qual        =ie_Qualifier
  448.  
  449. *»»» Call:    A0 = List of InputEvents
  450. *»»»        A1 = HandlerData (not used)
  451. HandlerCode    Push        Event/EList/A2
  452.         move.l        EList,Event
  453. ieLoop        move.l        Event,D0
  454.         beq        NoMoreEvents
  455.  
  456. *»»» Is it a RAWMOUSE event ?
  457.         cmpi.b        #IECLASS_RAWMOUSE,Class(Event)
  458.         bne.S        KeepEvent
  459.  
  460. *»»» Is it an RMB press event ?
  461.         cmpi.w        #IECODE_RBUTTON,Code(Event)
  462.         beq.S        PressRMB
  463.  
  464. *»»» Is it an RMB release event ?
  465.         cmpi.w        #IECODE_UP_PREFIX|IECODE_RBUTTON,Code(Event)
  466.         bne.S        KeepEvent
  467.  
  468. *»»» End the event modifying state
  469. ReleaseRMB    lea        State(PC),A2
  470.         bclr        #DOING_SHIFT,(A2)
  471.         beq.S        KeepEvent
  472.         bra.S        KillEvent
  473.  
  474. PressRMB
  475. *»»» Is the Left mousebutton pressed also ?
  476.         btst        #IEQUALIFIERB_LEFTBUTTON-8,Qual(Event)
  477.         beq.S        CheckRMBShift
  478.  
  479. *»»» Now either enable or disable this handler.
  480. ToggleState    lea        State(PC),A2
  481.         bchg        #ENABLED,(A2)
  482.         bra.S        UseAndKillEvent
  483.  
  484. *»»» See if we can use the RMB as a SHIFT key.
  485. CheckRMBShift    btst        #ENABLED,State(PC)
  486.         bne.S        NoMoreEvents
  487.  
  488. *»»» Is there an active screen ?
  489.         move.l        IntuiBase(PC),A2
  490.         move.l        ib_ActiveScreen(A2),D0
  491.         beq.S        UseAndKillEvent
  492.         move.l        D0,A2
  493.  
  494. *»»» Is the mouse in the screens titlebar ?
  495.         move.b        sc_BarHeight(A2),D0
  496.         ext.w        D0
  497.         cmp.w        sc_MouseY(A2),D0
  498.         bgt.S        KeepEvent
  499.  
  500. *»»» Is there an active window ?
  501.         move.l        IntuiBase(PC),A2
  502.         move.l        ib_ActiveWindow(A2),D0
  503.         beq.S        UseAndKillEvent
  504.         move.l        D0,A2
  505.  
  506. *»»» Is the RMBTRAP flag set ?
  507.         moveq        #RMBTRAP>>16,D0
  508.         and.w        wd_Flags(A2),D0
  509.         beq.S        UseAndKillEvent
  510.  
  511. *»»» The RMBTRAP flag is set, but does the window really want to
  512. *»»» know about mouse-button events ?
  513.         moveq        #MOUSEBUTTONS,D0
  514.         and.l        wd_IDCMPFlags(A2),D0
  515.         bne.S        KeepEvent
  516.  
  517. *»»» Enter the event modifying state
  518. UseAndKillEvent    lea        State(PC),A2
  519.         bset        #DOING_SHIFT,(A2)
  520.  
  521. *»»» Remove this event by making it into a NULL event
  522. KillEvent    clr.w        Class(Event)
  523. *»»» Just move on to next Event
  524. KeepEvent    btst        #DOING_SHIFT,State(PC)
  525.         beq.S        1$
  526. *»»» Clear the RBUTTON qualifier
  527.         bclr        #IEQUALIFIERB_RBUTTON-8,Qual(Event)
  528. *»»» Set a SHIFT qualifier
  529.         bset        #IEQUALIFIERB_LSHIFT,Qual+1(Event)
  530. 1$        move.l        Next(Event),Event
  531.         bra        ieLoop
  532. *»»» Lets return the list
  533. NoMoreEvents    move.l        EList,D0
  534.         Pop        Event/EList/A2
  535.         rts
  536. HandlerSize    =        *-IHS
  537. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  538. *»»» Input-handler end »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  539. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  540.  
  541. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  542. *»»» Data-definition start»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  543. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  544. DosName        dc.b        'dos.library',0
  545. IntuiName    dc.b        'intuition.library',0
  546. InputName    dc.b        'input.device',0
  547.         END
  548.  
  549.